#include "esp8266_uart.h"
#include "ringbuffer.h"


#if(ESP8266_RXBUF_SIZE & (ESP8266_RXBUF_SIZE - 1)) != 0
    #error "ESP8266_RXBUF_SIZE must be power of 2!"
#endif

#if(ESP8266_RXBUF_SIZE & (ESP8266_RXBUF_SIZE - 1)) != 0
    #error "ESP8266_RXBUF_SIZE must be power of 2!"
#endif

static unsigned char rxbuf[ESP8266_RXBUF_SIZE];
static unsigned char txbuf[ESP8266_TXBUF_SIZE];
static ring_buf_t rbsend, rbrecv;


void esp8266_uart_init(int bound)
{

    ring_buf_init(&rbsend, txbuf, sizeof(txbuf));
    ring_buf_init(&rbrecv, rxbuf, sizeof(rxbuf));

	RCC_APB1PeriphClockCmd(ESP8266_USART_CLK, ENABLE);		/* 使能USART3时钟 */
	RCC_APB2PeriphClockCmd(ESP8266_USART_GPIO_CLK, ENABLE); /* 使能GPIOB时钟 */

	gpio_conf(ESP8266_USART_TX_PORT, ESP8266_USART_TX_PIN, GPIO_Mode_AF_PP, GPIO_Speed_50MHz);		 /* USART3_TX GPIOB.10 */
	gpio_conf(ESP8266_USART_RX_PORT, ESP8266_USART_RX_PIN, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz); /* USART3_RX GPIOB.11初始化 */

	nvic_conf(ESP8266_USART_IRQ, 0, 0, ENABLE);											  /* Usart3 NVIC 配置 */
	uart_conf(ESP8266_USARTx, bound, USART_WordLength_8b, USART_StopBits_1, USART_Parity_No); /* USART 初始化设置 */
}

void esp8266_gpio_init(void)
{
	RCC_APB2PeriphClockCmd(ESP8266_CH_PD_CLK | ESP8266_RST_CLK, ENABLE);

	gpio_conf(ESP8266_CH_PD_PORT, ESP8266_CH_PD_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz); 	/* 配置CHIP_EN引脚 */
	gpio_conf(ESP8266_RST_PORT, ESP8266_RST_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz); 		/* 配置RST引脚 */
}


void esp8266_reset_init(void)
{
	GPIO_SetBits(ESP8266_RST_PORT, ESP8266_RST_PIN);
}

void esp8266_enable(void)
{
	GPIO_SetBits(ESP8266_CH_PD_PORT, ESP8266_CH_PD_PIN);
}

unsigned int esp8266_uart_write(const void *buf, unsigned int len)
{
    unsigned int ret = 0;

    ret = ring_buf_put(&rbsend, (unsigned char *)buf, len);
    USART_ITConfig(USART3, USART_IT_TXE, ENABLE);

    return ret;
}

unsigned int esp8266_uart_read(void *buf, unsigned int len)
{
    return ring_buf_get(&rbrecv, (unsigned char *)buf, len);
}

void esp8266_open(void)
{
	GPIO_SetBits(ESP8266_CH_PD_PORT, ESP8266_CH_PD_PIN);
}

void esp8266_close(void)
{
	GPIO_ResetBits(ESP8266_CH_PD_PORT, ESP8266_CH_PD_PIN);
}


void USART3_IRQHandler(void)
{
	unsigned char data;

	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
		data =USART_ReceiveData(USART3);	//读取接收到的数据
		ring_buf_put(&rbrecv, &data, 1);
	} 

	if(USART_GetITStatus(USART3, USART_IT_TXE) != RESET) {
		if(ring_buf_get(&rbsend, &data, 1)) {
			USART_SendData(USART3, data);
		} else {
			USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
		}
	}
	
	if(USART_GetITStatus(USART3, USART_IT_ORE) != RESET) {
		data = USART_ReceiveData(USART3);
	}
}





